/**
 * Copyright (C) 2018-2022
 * All rights reserved, Designed By www.yixiang.co
 * 注意：
 * 本软件为www.yixiang.co开发研制
 */
package co.yixiang.modules.member.serviceimpl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.text.CharSequenceUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import co.yixiang.cache.Cache;
import co.yixiang.cache.CachePrefix;
import co.yixiang.common.context.ThreadContextHolder;
import co.yixiang.common.enums.ResultCode;
import co.yixiang.common.exception.ServiceException;
import co.yixiang.common.service.impl.BaseServiceImpl;
import co.yixiang.common.utils.*;
import co.yixiang.dozer.service.IGenerator;
import co.yixiang.modules.connect.entity.dto.WechatMPLoginParams;
import co.yixiang.modules.member.entity.domain.YxUser;
import co.yixiang.modules.member.entity.domain.YxUserBill;
import co.yixiang.modules.member.entity.dto.YxUserDto;
import co.yixiang.modules.member.entity.dto.YxUserFrom;
import co.yixiang.modules.member.entity.dto.YxUserQueryCriteria;
import co.yixiang.modules.member.entity.vo.YxUserVo;
import co.yixiang.modules.member.mapper.UserMapper;
import co.yixiang.modules.member.service.YxUserBillService;
import co.yixiang.modules.member.service.YxUserService;
import co.yixiang.modules.security.entity.domain.Token;
import co.yixiang.modules.security.entity.vo.AuthUser;
import co.yixiang.modules.shop.entity.dto.UserMoneyDto;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.github.pagehelper.PageInfo;
import lombok.AllArgsConstructor;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.math.BigDecimal;
import java.nio.charset.StandardCharsets;
import java.security.AlgorithmParameters;
import java.security.Security;
import java.util.*;

// 默认不使用缓存
//import org.springframework.cache.annotation.CacheConfig;
//import org.springframework.cache.annotation.CacheEvict;
//import org.springframework.cache.annotation.Cacheable;

/**
 * @author hupeng
 * @date 2020-05-12
 */
@Service
@Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = Exception.class)
public class YxUserServiceImpl extends BaseServiceImpl<UserMapper, YxUser> implements YxUserService {
    @Autowired
    private  IGenerator generator;
    @Autowired
    private  UserMapper yxUserMapper;
    @Autowired
    private  YxUserBillService yxUserBillService;
    @Autowired
    private Cache cache;




    /**
     * 注册方法抽象
     *
     * @param member
     */
    private void registerHandler(YxUser member) {
        member.setUid(SnowFlake.getIdStr());
        //保存会员
        this.save(member);
    }
    /**
     * 成功登录，则检测cookie中的信息，进行会员绑定
     *
     * @param member 会员
     */
    private void loginBindUser(YxUser member) {
        //获取cookie存储的信息
        // String uuid = CookieUtil.getCookie(ConnectService.CONNECT_COOKIE, ThreadContextHolder.getHttpRequest());
        // String connectType = CookieUtil.getCookie(ConnectService.CONNECT_TYPE, ThreadContextHolder.getHttpRequest());
        //如果联合登陆存储了信息
//        if (CharSequenceUtil.isNotEmpty(uuid) && CharSequenceUtil.isNotEmpty(connectType)) {
//            try {
//                //获取信息
//                ConnectAuthUser connectAuthUser = getConnectAuthUser(uuid, connectType);
//                if (connectAuthUser == null) {
//                    return;
//                }
//                Connect connect = connectService.queryConnect(
//                        ConnectQueryDTO.builder().unionId(connectAuthUser.getUuid()).unionType(connectType).build()
//                );
//                if (connect == null) {
//                    connect = new Connect(member.getId(), connectAuthUser.getUuid(), connectType);
//                    connectService.save(connect);
//                }
//            } catch (ServiceException e) {
//                throw e;
//            } catch (Exception e) {
//                log.error("绑定第三方联合登陆失败：", e);
//            } finally {
//                //联合登陆成功与否，都清除掉cookie中的信息
//                CookieUtil.delCookie(ConnectService.CONNECT_COOKIE, ThreadContextHolder.getHttpResponse());
//                CookieUtil.delCookie(ConnectService.CONNECT_TYPE, ThreadContextHolder.getHttpResponse());
//            }
//        }

    }


    @Override
    //@Cacheable
    public Map<String, Object> queryAll(YxUserQueryCriteria criteria, Pageable pageable) {
        getPage(pageable);
        PageInfo<YxUser> page = new PageInfo<>(queryAll(criteria));
        Map<String, Object> map = new LinkedHashMap<>(2);
        map.put("content", generator.convert(page.getList(), YxUserDto.class));
        map.put("totalElements", page.getTotal());
        return map;
    }


    @Override
    //@Cacheable
    public List<YxUser> queryAll(YxUserQueryCriteria criteria) {
        return baseMapper.selectList(QueryHelpPlus.getPredicate(YxUser.class, criteria));
    }

    @Override
    public YxUserVo binPhone(YxUserFrom from) {
        final AuthUser authUser = SecurityUtils.getAuthUser();
        final YxUser byId = getById(authUser.getUuid());
        if (ObjectUtil.isEmpty(byId)) {
            throw new ServiceException(ResultCode.USER_NOT_EXIST);
        }
        byId.setPhone(from.getPhone());
        updateById(byId);
        return BeanUtil.copyProperties(byId,YxUserVo.class);
    }


    @Override
    public void download(List<YxUserDto> all, HttpServletResponse response) throws IOException {
        List<Map<String, Object>> list = new ArrayList<>();
        for (YxUserDto yxUser : all) {
            Map<String, Object> map = new LinkedHashMap<>();
            map.put("用户账户(跟accout一样)", yxUser.getUsername());
            map.put("用户账号", yxUser.getAccount());
            map.put("用户密码（跟pwd）", yxUser.getPassword());
            map.put("用户密码", yxUser.getPwd());
            map.put("真实姓名", yxUser.getRealName());
            map.put("生日", yxUser.getBirthday());
            map.put("身份证号码", yxUser.getCardId());
            map.put("用户备注", yxUser.getMark());
            map.put("合伙人id", yxUser.getPartnerId());
            map.put("用户分组id", yxUser.getGroupId());
            map.put("用户昵称", yxUser.getNickname());
            map.put("用户头像", yxUser.getAvatar());
            map.put("手机号码", yxUser.getPhone());
            map.put("添加时间", yxUser.getAddTime());
            map.put("添加ip", yxUser.getAddIp());
            map.put("最后一次登录时间", yxUser.getLastTime());
            map.put("最后一次登录ip", yxUser.getLastIp());
            map.put("用户余额", yxUser.getNowMoney());
            map.put("佣金金额", yxUser.getBrokeragePrice());
            map.put("用户剩余积分", yxUser.getIntegral());
            map.put("连续签到天数", yxUser.getSignNum());
            map.put("1为正常，0为禁止", yxUser.getStatus());
            map.put("等级", yxUser.getLevel());
            map.put("推广元id", yxUser.getSpreadUid());
            map.put("推广员关联时间", yxUser.getSpreadTime());
            map.put("用户类型", yxUser.getUserType());
            map.put("是否为推广员", yxUser.getIsPromoter());
            map.put("用户购买次数", yxUser.getPayCount());
            map.put("下级人数", yxUser.getSpreadCount());
            map.put("清理会员时间", yxUser.getCleanTime());
            map.put("详细地址", yxUser.getAddres());
            map.put("管理员编号 ", yxUser.getAdminid());
            map.put("用户登陆类型，h5,wechat,routine", yxUser.getLoginType());
            list.add(map);
        }
        FileUtil.downloadExcel(list, response);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void onStatus(String uid, int status) {
        if (status == 1) {
            status = 0;
        } else {
            status = 1;
        }

        yxUserMapper.updateOnstatus(status, uid);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateMoney(UserMoneyDto param) {
        YxUserDto userDTO = generator.convert(getById(param.getUid()), YxUserDto.class);
        Double newMoney = 0d;
        String mark = "";
        String type = "system_add";
        Integer pm = 1;
        String title = "系统增加余额";
        if (param.getPtype() == 1) {
            mark = "系统增加了" + param.getMoney() + "余额";
            newMoney = NumberUtil.add(userDTO.getNowMoney(), param.getMoney()).doubleValue();
        } else {
            title = "系统减少余额";
            mark = "系统扣除了" + param.getMoney() + "余额";
            type = "system_sub";
            pm = 0;
            newMoney = NumberUtil.sub(userDTO.getNowMoney(), param.getMoney()).doubleValue();
            if (newMoney < 0) {
                newMoney = 0d;
            }

        }
        YxUser user = new YxUser();
        user.setUid(userDTO.getUid().toString());
        user.setNowMoney(BigDecimal.valueOf(newMoney));
        saveOrUpdate(user);

        YxUserBill userBill = new YxUserBill();
        userBill.setUid(userDTO.getUid());
        userBill.setLinkId("0");
        userBill.setPm(pm);
        userBill.setTitle(title);
        userBill.setCategory("now_money");
        userBill.setType(type);
        userBill.setNumber(BigDecimal.valueOf(param.getMoney()));
        userBill.setBalance(BigDecimal.valueOf(newMoney));
        userBill.setMark(mark);
        userBill.setStatus(1);
        yxUserBillService.save(userBill);
    }

    @Override
    public void incBrokeragePrice(double price, String uid) {
        yxUserMapper.incBrokeragePrice(price, uid);
    }

    @Override
    public void updateUser(YxUserFrom yxUserFrom) {
        final AuthUser authUser = SecurityUtils.getAuthUser();
        final YxUser byId = getById(authUser.getUuid());
        if (ObjectUtil.isEmpty(byId)) {
            throw  new ServiceException(ResultCode.USER_NOT_EXIST);
        }
        byId.setAvatar(yxUserFrom.getAvatar());
        byId.setNickName(yxUserFrom.getNickName());
        if (ObjectUtil.isNotEmpty(yxUserFrom.getPhone())) {
            byId.setPhone(yxUserFrom.getPhone());
        }
        updateById(byId);
    }
}
